using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;


namespace CoreCalc.SheetDefinedFunctions.CompOnlyNeededCells
{
    public class ConditionDictionary:IEnumerable<System.Collections.Generic.KeyValuePair<FullCellAddr, Condition>>
    {
        private Dictionary<FullCellAddr, Condition> internalDictionary;

        public ConditionDictionary()
        {
            internalDictionary = new Dictionary<FullCellAddr, Condition>();
        }

        public void Add(FullCellAddr key, Condition value)
        {
            internalDictionary.Add(key, value);
        }

        public void Add(FullCellAddr key, CGExpr expression, bool expressionNeedToBeTrue)
        {
            internalDictionary.Add(key, new Condition(expression, expressionNeedToBeTrue));
        }

        /// <summary>
        /// Use when the condition is true (ex. a normal reference is true)
        /// </summary>
        /// <param name="key"></param>
        public void Add(FullCellAddr key)
        {
            internalDictionary.Add(key, new Condition());
        }

        public void AddAlwaysTrue(FullCellAddr key)
        {
            Condition cond = new Condition();
            cond.ShouldAlwaysBeevaluatedSuper = true;
            internalDictionary.Add(key, cond);
        }

        public bool TryGetValue(FullCellAddr key, out Condition value)
        {
            return internalDictionary.TryGetValue(key, out value);
        }

        public void And(Condition other)
        {
            if (other.ShouldAlwaysBeevaluated)//equals   true && condition => condition
                return;

            foreach (KeyValuePair<FullCellAddr, Condition> pair in this)
            {
                pair.Value.And(other);
            }
        }

        public void Or(ConditionDictionary other)
        {
            foreach (KeyValuePair<FullCellAddr, Condition> pair in other)
            {
                Condition cond;
                if (TryGetValue(pair.Key, out cond))
                {
                    cond.Or(pair.Value);
                }
                else
                    Add(pair.Key, pair.Value);

            }
        }

     

        public IEnumerator GetEnumerator()
        {
            return internalDictionary.GetEnumerator();
        }

        internal void Clear()
        {
            internalDictionary.Clear();
        }

        IEnumerator<System.Collections.Generic.KeyValuePair<FullCellAddr, Condition>>
            IEnumerable<System.Collections.Generic.KeyValuePair<FullCellAddr, Condition>>.GetEnumerator()
        {
            return this.internalDictionary.GetEnumerator();
        }
    }
}
